package helper

import (
	"gin-ranking/api/lock/dao"
	"gin-ranking/common/byteUtils"
	"gin-ranking/common/util"
	tcpMsg "gin-ranking/common/zinx/tcp/lock/lockMessage"
	set "github.com/duke-git/lancet/v2/datastructure/set"
	"github.com/duke-git/lancet/v2/datetime"
)

var byteBufCache = util.NewCacheMap[string, byteUtils.ByteBuf]()

func SetByteBufCache(lockId string, bytes byteUtils.ByteBuf) {
	byteBufCache.Set(lockId, bytes)
}

func GetByteBufCache(lockId string) *byteUtils.ByteBuf {
	get, _ := byteBufCache.Get(lockId)
	return &get
}

// DefaultCheckMd5Sign 校验签名
func DefaultCheckMd5Sign(message *tcpMsg.TcpMessage) bool {

	// 解密字节数组
	OriginBizDataBytes := message.OriginBizDataBytes
	beforeMd5SignBytes := OriginBizDataBytes[0 : len(OriginBizDataBytes)-16]
	receiveMd5SignBytes := OriginBizDataBytes[len(OriginBizDataBytes)-16 : len(OriginBizDataBytes)]
	return util.CheckMd5Sign(beforeMd5SignBytes, receiveMd5SignBytes, util.HexToBytes(message.SignKey))
}

// FillLockKey 填充锁密钥
func FillLockKey(message *tcpMsg.TcpMessage) {
	deviceLockInfo := dao.DeviceLockInfoDao{}.QueryById(message.LockId)
	if len(deviceLockInfo.SignKey) <= 0 {
		panic("锁没注册，请先注册，lockId：" + message.LockId)
	}
	message.SignKey = deviceLockInfo.SignKey
	message.EncryptKey = deviceLockInfo.EncryptKey
}

// LockAction 锁执行动作
type LockAction struct {
	Action int
	Name   string
}

var (
	LockActionCode0X1010 = LockAction{0x1010, "锁唤醒查询指令"}

	// LockActionCodeList  执行码集合
	LockActionCodeList = set.New[int](LockActionCode0X1010.Action)
)

// CheckActionCode 判断执行动作
func CheckActionCode(actionCode int) bool {
	return LockActionCodeList.Contain(actionCode)
}

// BuildRequestMd5SignBytes 构建md5加密字节数组
func BuildRequestMd5SignBytes(dataBytes []byte, signKeyBytes []byte) []byte {
	return util.BytesAppend(dataBytes, util.Md5(util.BytesAppend(dataBytes, signKeyBytes)))
}

// BuildRequestIsEncryptDataBytes 构建是否加解密数据
func BuildRequestIsEncryptDataBytes(dataBytes []byte, encryptType int, encryptKey string) []byte {

	if encryptType == 0 || len(encryptKey) < 1 {
		return dataBytes
	}

	if encryptType == 3 && len(encryptKey) == 32 {
		return util.Sm4Encrypt(util.HexToBytes(encryptKey), dataBytes)
	}
	return dataBytes
}

// BuildDefaultRequestData 获取默认下发指令
func BuildDefaultRequestData(lockId string) tcpMsg.TcpMessage {

	deviceLockInfo := dao.DeviceLockInfoDao{}.QueryById(lockId)

	if len(deviceLockInfo.SignKey) < 0 {
		panic("锁没注册，请先注册，lockId：" + lockId)
	}

	// 加密类型
	encryptType := deviceLockInfo.EncryptMode

	// 查询外层，加密密钥
	encryptKey := deviceLockInfo.EncryptKey

	// 查询外层，加密密钥
	signKey := deviceLockInfo.SignKey

	// 服务器当前时间，锁端可用于同步时间
	timeBytes := util.Uint64ToBytesBig(uint64(datetime.NewUnixNow().ToUnix()))[4:8]

	// 查询结果，0：无下发数据，>0：待下发记录数

	nBCommandRecordV2ListSize := dao.NbCommandRecordV2Dao{}.QueryCountById(lockId)

	resultDataBytes := util.Uint32ToBytesBig(uint32(nBCommandRecordV2ListSize))[2:4]

	// 锁签名密钥
	publicKeyBytes := util.HexToBytes(signKey)

	// 签名数据
	dataBytes := BuildRequestMd5SignBytes(util.BytesAppend(timeBytes, resultDataBytes), publicKeyBytes)

	// 对数据加密
	encryptDataBytes := BuildRequestIsEncryptDataBytes(dataBytes, encryptType, encryptKey)

	// 返回消息对象
	return tcpMsg.NewTcpMessage(0x11, encryptType, lockId,
		LockActionCode0X1010.Action, 0, len(dataBytes), len(encryptDataBytes), encryptDataBytes)

}
